
module FdHelper where

import Data.List
import Data.IORef
import Monad
import Control.Monad.Error

import FdType

io = liftIO

findM :: (Monad m) => (a -> m Bool) -> [a] -> m (Maybe a)
findM cond [] = return Nothing
findM cond (x:xs) = do {
	ok <- cond x;
	if ok then 
		return $ Just x
	else 
 		findM cond xs;		
}

toVal :: Expr -> ThrowsError Val
toVal (Value val) = return val
toVal _ = throwError $ Default $ "not a value"

toInt = round

isDefine :: Expr -> Bool
isDefine (Define _ _) = True
isDefine _ = False
 
isBreak :: Expr -> Bool
isBreak Break = True
isBreak _ = False

isReturn :: Expr -> Bool
isReturn (Return _) = True
isReturn _ = False


isFalse val = 
	isNotFalse val >>= return . not

isNotFalse :: Val -> Fineday Bool
isNotFalse Nil            = return False
isNotFalse (Number 0)     = return False
isNotFalse (Bool False)   = return False
isNotFalse (String strRef)= do {
	str <- io $ readIORef strRef;	
	return $ (length str) /= 0;
}
isNotFalse (Array arrRef) = do {
	arr <- io $ readIORef arrRef;	
	return $ (length arr) /= 0;
}
isNotFalse _              = return True

typeOf :: Val -> String 
typeOf a = 
    case a of 
		(Number _) ->    "Number"
		(Bool _) ->      "Bool"
		(String _) ->    "String"
		(Function _) ->  "Function"
		(Array _) ->     "Array"
		(Hash _) ->      "Hash"
		(Nil) ->         "Nil"
